﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Windows.Forms;

namespace BatailleNavale
{
    class Robot
    {
        private List<Bateau> bateauxJoueur;
        private string[] casesDejaTirer = new string[100];
        private int NbArray=0;
        private Form1 _form;
        private int degatTotaux=0;
        private bool sensbool = false; //regarde si on a déjà assigné le sens.
        private int sensAttaque; // 0 = gauche 1 = droite 2 = haut, 3 = bas
        private List<string> coordAVerif = new List<string>();


        public void AddForm(Form1 _form)
        {
            this._form = _form;
        }
        public void AjoutDesBateaux(List<Bateau> lesBateaux)
        {
            this.bateauxJoueur = lesBateaux;
        }

        private bool VerifCaseDejaTirer(string caseAVérifier) //renvoi faux si la case a déjà été tirée
        {
            bool verif = true;
            foreach (string cases in casesDejaTirer)
            {
                if (cases == caseAVérifier)
                {
                    verif = false;
                }
            }
            return verif;
        }

        public void TirerZoneJoueur() 
        {
            if (coordAVerif.Count == 0)
            {
                sensbool = false;
                bool permissionDeTirer = false;
                int coordX;
                int coordY;
                string caseNameATirer;
                Random nbsAléa = new Random();
                while (permissionDeTirer == false)
                {
                    coordY = nbsAléa.Next(11, 21);
                    coordX = nbsAléa.Next(1, 11);
                    caseNameATirer = coordY.ToString() + "," + coordX.ToString();
                    if (((coordX % 2 == 0 && coordY % 2 != 0) || (coordX % 2 != 0 && coordY % 2 == 0)) && (VerifCaseDejaTirer(caseNameATirer)))
                    {
                        permissionDeTirer = true;
                        casesDejaTirer[NbArray] = caseNameATirer;
                        NbArray++;
                        AttaquerCase(caseNameATirer);
                    }
                }
            }
            else { 
                //on génère le sens aléatoirement 0 pour gauche, 1 pour droite 2pour haut, 3 pour bas tant qu'il n'y a pas de collision
                // si il n'a pas été déjà générén, sinon on le génère.
                if (sensbool == false)
                {
                    Random rd = new Random();
                    bool verifCol = false;
                    while (verifCol == false)
                    {
                        int testSens = rd.Next(0, 4);
                        string caseSuivante = GetCaseSuivante(coordAVerif[0], testSens);
                        if (caseSuivante != "col")
                        {
                            verifCol = true;
                            sensbool = true;
                            sensAttaque = testSens;
                            casesDejaTirer[NbArray] = caseSuivante;
                            NbArray++;
                            AttaquerCase(caseSuivante);
                        }
                    }
                }
                else {
                    string caseSuivante = GetCaseSuivante(coordAVerif[coordAVerif.Count-1], sensAttaque);
                    if (caseSuivante != "col")
                    {
                        casesDejaTirer[NbArray] = caseSuivante;
                        NbArray++;
                        AttaquerCase(caseSuivante);
                    }
                    else // sinon on change de coté opposé
                    {
                        ChangerSensOppose();
                        caseSuivante = GetCaseSuivante(coordAVerif[0], sensAttaque);
                        if (caseSuivante != "col")
                        {
                            casesDejaTirer[NbArray] = caseSuivante;
                            NbArray++;
                            AttaquerCase(caseSuivante);
                        }
                        else { // sinon on change de coté horrizontal/vertical
                            ChangerSens();
                            caseSuivante = GetCaseSuivante(coordAVerif[0], sensAttaque);
                            if (caseSuivante != "col")
                            {
                                casesDejaTirer[NbArray] = caseSuivante;
                                NbArray++;
                                AttaquerCase(caseSuivante);
                            }
                            else { //sinon ont rechange de coté opposé
                                ChangerSensOppose();
                                caseSuivante = GetCaseSuivante(coordAVerif[0], sensAttaque);
                                if (caseSuivante != "col")
                                {
                                    casesDejaTirer[NbArray] = caseSuivante;
                                    NbArray++;
                                    AttaquerCase(caseSuivante);
                                }
                            }
                        }
                    }
                }

                //si pas de collision + pas déjà clické, ont prends la dernière case touché, 

            }
            
        } //tire sur les bateaux ennemis.

        private void AttaquerCase(string caseName) //Attaque une case cible
        {
            bool explosion = false; // vrai si touché
            foreach (Bateau b in bateauxJoueur)
            {
                foreach (string cases in b.getCases())
                {
                    if (cases == caseName) //Touché !
                    {
                        explosion = true; //touché donc explosion
                        coordAVerif.Add(caseName); // on rajoute la cible touché dans la list
                        degatTotaux++; //on ajoute un degat pour le controle de victoire/défaite et le score
                        b.AddDegatBateau();// ajoute un dégat au bateau
                        if (b.BateauDetruit())
                        {
                            foreach (string uneCase in b.getCases())
                            {
                                coordAVerif.Remove(uneCase); // on enlève les cases du bateau qu'on vient de couler
                            }
                            
                        }
                        
                    }
                }

            }
            AttaquerPicturBox(explosion, caseName);
            if (degatTotaux == 23)
            {
                string message = "L'ordinateur remporte la victoire";
                string caption = "Défaite";
                DialogResult result;
                result = MessageBox.Show(message, caption);
                _form.Close();


            }
        }
        private void AttaquerPicturBox(bool exp, string caseName) //attaque la picture box pour lui donner une image en fonction de toucher ou coulé.
        {
            foreach (PictureBox pB in _form.panel1Tab.Controls)
            {
                if (pB.Name == caseName)
                {
                    if (exp)
                    {
                        pB.Image = BatailleNavale.Properties.Resources.explosion;
                    }
                    else {
                        pB.Image = BatailleNavale.Properties.Resources.cercleVert;
                    }
                }
 
            }
        }

        public string[] GetCasesACote(string caseName) //retourne les cases a coté de caseName, avec verif des collisions.
        {
            int indexeur=0;
            string caseAcote;
            string[] lesCasesACote = new string[4];
            string[] separation= caseName.Split(',');
            int coordY = Convert.ToInt16(separation[0]);
            int coordX = Convert.ToInt16(separation[1]);
            if (coordY - 1 != 10)
            {
                caseAcote = (coordY - 1).ToString() + "," + coordX.ToString();
                if (casesDejaTirer.Contains(caseAcote)==false)
                {
                    lesCasesACote[indexeur] = caseAcote;
                    indexeur++;
                }
            }
            if (coordY + 1 != 21)
            {
                caseAcote = (coordY + 1).ToString() + "," + coordX.ToString();
                if (casesDejaTirer.Contains(caseAcote) == false)
                {
                    lesCasesACote[indexeur] = caseAcote;
                    indexeur++;
                }
            }
            if (coordX - 1 != 0)
            {
                caseAcote = coordY.ToString() + "," + (coordX - 1).ToString();
                if (casesDejaTirer.Contains(caseAcote) ==false)
                {
                    lesCasesACote[indexeur] = caseAcote;
                    indexeur++;
                }
            }
            if (coordX + 1 != 11)
            {
                caseAcote = coordY.ToString() + "," + (coordX + 1).ToString();
                if (casesDejaTirer.Contains(caseAcote)==false)
                {
                    lesCasesACote[indexeur] = caseAcote;
                    indexeur++;
                }
            }
            return lesCasesACote;
        }

        private string GetCaseSuivante(string nomCase, int sens) //donne la case suivante, renvoie "col" si la case ne peut être attaqué
        {
            string[] separation = nomCase.Split(',');
            int coordY = Convert.ToInt16(separation[0]);
            int coordX = Convert.ToInt16(separation[1]);
            switch (sens)
            {
                case 2:
                    coordY--;
                    break;
                case 3:
                    coordY++;
                    break;
                case 0:
                    coordX--;
                    break;
                case 1:
                    coordX++;
                    break;
            }
            string laCase = coordY.ToString() + "," + coordX.ToString();
            if (coordX > 0 && coordX < 11 && coordY > 10 && coordY < 21 && VerifCaseDejaTirer(laCase))
            {
                return laCase;
            }else{
                return "col";
            }

 
        }
        private void ChangerSensOppose()
        {
            switch (sensAttaque)
            {
                case 0:
                    sensAttaque = 1;
                    break;
                case 1:
                    sensAttaque = 0;
                    break;
                case 2:
                    sensAttaque = 3;
                    break;
                case 3:
                    sensAttaque = 2;
                    break;
            }
        } // inverse le sens haut vers bas, gauche vers droite.
        private void ChangerSens()
        {
            switch (sensAttaque)
            {
                case 0:
                    sensAttaque = 2;
                    break;
                case 1:
                    sensAttaque = 3;
                    break;
                case 2:
                    sensAttaque = 0;
                    break;
                case 3:
                    sensAttaque = 1;
                    break;
            }
        } //change le sens, horrizontal/ vertical
    }
}
